#include <iostream>
#include <unistd.h>
#include <signal.h>

void PrintfPending(sigset_t &pending)
{
    std::cout << "cur process pid : " << getpid() << "\n";
    std::cout << "pending signo :";
    for (int signo = 31; signo >= 1; signo--)
    {
        if (sigismember(&pending, signo))
        {
            std::cout << 1;
        }
        else
        {
            std::cout << 0;
        }
    }
    std::cout << "\n";
}

void handler(int signo)
{
    std::cout << signo << " 号信号被递达!!!" << std::endl;

    std::cout << "-------------------------------" << std::endl;
    sigset_t pending;
    sigpending(&pending);
    PrintfPending(pending);
    std::cout << "-------------------------------" << std::endl;
}

int main()
{
    signal(2, handler);

    sigset_t block_set, old_set;
    sigemptyset(&block_set);
    sigemptyset(&old_set);
    sigaddset(&block_set, 2);
    sigaddset(&block_set, 40);

    sigprocmask(SIG_BLOCK, &block_set, &old_set);

    int cnt = 20;
    while (true)
    {
        sigset_t pending;
        sigpending(&pending);

        PrintfPending(pending);

        if (cnt == 0)
        {
            std::cout << "解除对2号信号的屏蔽!!!" << std::endl;
            sigprocmask(SIG_SETMASK, &old_set, &block_set);
        }
        cnt--;
        sleep(2);
    }
    return 0;
}

// void sigcb(int sig)
// {
//     std::cout << "get a sig : " << sig << std::endl;
// }

// struct sigaction {
//     void (*sa_handler)(int);
//     void (*sa_sigaction)(int, siginfo_t *, void *);
//     sigset_t sa_mask;
//     int sa_flags;
//     void (*sa_restorer)(void);
// }

// sa_handler此参数和signal()的参数handler相同，代表新的信号处理函数
// sa_mask 用来设置在处理该信号时暂时将sa_mask 指定的信号集搁置
// sa_flags 用来设置信号处理的其他相关操作，下列的数值可用。 
// SA_RESETHAND：当调用信号处理函数时，将信号的处理函数重置为缺省值SIG_DFL
// SA_RESTART：如果信号中断了进程的某个系统调用，则系统自动启动该系统调用
// SA_NODEFER ：一般情况下， 当信号处理函数运行时，内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记，那么在该信号处理函数运行时，内核将不会阻塞该信号。

// int main()
// {
//     struct sigaction act;
//     act.sa_handler = sigcb;
//     sigaction(2, &act, nullptr);
//     while (true)
//     {
//         std::cout << "process is running , pid : " << getpid() << std::endl;
//         sleep(1);
//     }
//     return 0;
// }

// int main()
// {
//     signal(2, sigcb);
//     while (true)
//     {
//         std::cout << "process is running , pid : " << getpid() << std::endl;
//         sleep(1);
//     }
//     return 0;
// }